#!/bin/bash

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 🚀 自动化部署脚本 - 三步走快速部署
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

set -e  # 遇到错误立即退出

# ========================================
# 配置区
# ========================================
REMOTE_HOST="124.156.188.238"
REMOTE_USER="root"
REMOTE_PASSWORD="a1039385286."
REMOTE_PATH="/root/internalNetBridge/server"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# ========================================
# 函数定义
# ========================================

print_step() {
    echo ""
    echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    echo -e "${GREEN}$1${NC}"
    echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}

print_error() {
    echo -e "${RED}❌ $1${NC}"
}

print_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

# 检查并选择SSH方法
setup_ssh_method() {
    if command -v sshpass &> /dev/null; then
        USE_SSHPASS=true
        return 0
    fi
    
    if command -v expect &> /dev/null; then
        USE_EXPECT=true
        return 0
    fi
    
    if ssh -o BatchMode=yes -o ConnectTimeout=5 "$REMOTE_USER@$REMOTE_HOST" exit 2>/dev/null; then
        USE_SSH_KEY=true
        return 0
    fi
    
    print_error "未找到SSH认证工具，请安装 sshpass 或 expect，或配置SSH密钥"
    exit 1
}

# SCP上传文件函数
scp_upload() {
    local local_file="$1"
    local remote_file="$2"
    
    if [ "$USE_SSHPASS" = true ]; then
        sshpass -p "$REMOTE_PASSWORD" scp -o StrictHostKeyChecking=no "$local_file" "$REMOTE_USER@$REMOTE_HOST:$remote_file"
    elif [ "$USE_EXPECT" = true ]; then
        expect << EOF
set timeout 60
spawn scp -o StrictHostKeyChecking=no "$local_file" $REMOTE_USER@$REMOTE_HOST:$remote_file
expect {
    "password:" {
        send "$REMOTE_PASSWORD\r"
        exp_continue
    }
    eof
}
EOF
    else
        scp -o StrictHostKeyChecking=no "$local_file" "$REMOTE_USER@$REMOTE_HOST:$remote_file"
    fi
}

# SSH命令封装
ssh_exec() {
    if [ ! -t 0 ]; then
        local temp_script
        temp_script=$(mktemp)
        cat > "$temp_script"
        local remote_script="/tmp/deploy_script_$$.sh"
        
        scp_upload "$temp_script" "$remote_script"
        rm -f "$temp_script"
        
        local cmd="bash $remote_script && rm -f $remote_script"
        if [ "$USE_SSHPASS" = true ]; then
            sshpass -p "$REMOTE_PASSWORD" ssh -tt -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" "$cmd"
        elif [ "$USE_EXPECT" = true ]; then
            expect << EOF
set timeout 300
log_user 1
spawn ssh -tt -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST "$cmd"
expect {
    "password:" {
        send "$REMOTE_PASSWORD\r"
        exp_continue
    }
    eof
}
EOF
        else
            ssh -tt -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" "$cmd"
        fi
    else
        local cmd="$*"
        if [ "$USE_SSHPASS" = true ]; then
            sshpass -p "$REMOTE_PASSWORD" ssh -tt -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" "$cmd"
        elif [ "$USE_EXPECT" = true ]; then
            expect << EOF
set timeout 120
log_user 1
spawn ssh -tt -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST "$cmd"
expect {
    "password:" {
        send "$REMOTE_PASSWORD\r"
        exp_continue
    }
    eof
}
EOF
        else
            ssh -tt -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" "$cmd"
        fi
    fi
}

# ========================================
# 主流程
# ========================================

print_step "🚀 开始快速部署"

# 准备工作：检查SSH工具
echo "📦 检查SSH工具..."
setup_ssh_method
print_success "SSH工具已就绪"

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 第一步：构建server
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
print_step "🔨 第一步：构建 server"

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SCRIPT_DIR/server" || exit 1

# 检查Go环境
if ! command -v go &> /dev/null; then
    print_error "Go未安装！请先安装Go"
    exit 1
fi

echo "📍 当前Go版本: $(go version)"
echo "📂 编译目标: linux/amd64"
echo ""

# 清理并创建目录
rm -f bin/server
mkdir -p bin

# 开始编译
echo "⚙️  开始编译..."
START_TIME=$(date +%s)

# 🔥 使用Go 1.24(避免Go 1.25.1的cgroup bug)
export PATH="/opt/homebrew/opt/go@1.24/bin:$PATH"
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -trimpath -o bin/server .

END_TIME=$(date +%s)
BUILD_TIME=$((END_TIME - START_TIME))

if [ -f "bin/server" ]; then
    FILE_SIZE=$(du -h bin/server | cut -f1)
    print_success "编译完成！"
    echo "   📦 文件大小: $FILE_SIZE"
    echo "   ⏱️  编译耗时: ${BUILD_TIME}秒"
else
    print_error "编译失败！"
    exit 1
fi

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 第二步：上传服务器
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
print_step "📤 第二步：上传服务器"

echo "🛑 停止远程服务..."
ssh_exec << 'STOP_EOF'
    # 停止服务
    if pgrep -f "bin/server" > /dev/null; then
        pkill -f "bin/server" || true
        sleep 2
        if pgrep -f "bin/server" > /dev/null; then
            pkill -9 -f "bin/server" || true
            sleep 1
        fi
        echo "✅ 服务已停止"
    else
        echo "⚠️  服务未运行"
    fi
    
    # 创建目录
    mkdir -p /root/internalNetBridge/server/bin
    mkdir -p /root/internalNetBridge/server/logs
STOP_EOF

echo ""
echo "📤 上传二进制文件..."
START_TIME=$(date +%s)

scp_upload "bin/server" "$REMOTE_PATH/bin/server"

END_TIME=$(date +%s)
UPLOAD_TIME=$((END_TIME - START_TIME))

if [ $? -eq 0 ]; then
    print_success "上传完成！"
    echo "   ⏱️  上传耗时: ${UPLOAD_TIME}秒"
else
    print_error "上传失败！"
    exit 1
fi

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 第三步：启动服务
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
print_step "🚀 第三步：启动服务"

ssh_exec << 'START_EOF'
    cd /root/internalNetBridge/server
    
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "🔍 检查端口占用情况..."
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    
    # 检查8080端口是否被占用
    if netstat -tlnp 2>/dev/null | grep -q ":8080 " || ss -tlnp 2>/dev/null | grep -q ":8080 "; then
        echo "⚠️  检测到8080端口被占用，正在释放..."
        
        # 查找占用8080端口的进程
        PID_8080=$(netstat -tlnp 2>/dev/null | grep ":8080 " | awk '{print $7}' | cut -d'/' -f1 | head -1)
        if [ -z "$PID_8080" ]; then
            PID_8080=$(ss -tlnp 2>/dev/null | grep ":8080 " | grep -oP 'pid=\K[0-9]+' | head -1)
        fi
        
        if [ -n "$PID_8080" ]; then
            echo "📍 发现进程 PID=$PID_8080 占用8080端口"
            kill $PID_8080 2>/dev/null || true
            sleep 2
            
            # 如果还在运行，强制终止
            if ps -p $PID_8080 > /dev/null 2>&1; then
                echo "⚠️  强制终止进程 $PID_8080"
                kill -9 $PID_8080 2>/dev/null || true
                sleep 1
            fi
            echo "✅ 8080端口已释放"
        fi
    else
        echo "✅ 8080端口未被占用"
    fi
    
    # 检查8088端口是否被占用
    if netstat -tlnp 2>/dev/null | grep -q ":8088 " || ss -tlnp 2>/dev/null | grep -q ":8088 "; then
        echo "⚠️  检测到8088端口被占用，正在释放..."
        
        PID_8088=$(netstat -tlnp 2>/dev/null | grep ":8088 " | awk '{print $7}' | cut -d'/' -f1 | head -1)
        if [ -z "$PID_8088" ]; then
            PID_8088=$(ss -tlnp 2>/dev/null | grep ":8088 " | grep -oP 'pid=\K[0-9]+' | head -1)
        fi
        
        if [ -n "$PID_8088" ]; then
            echo "📍 发现进程 PID=$PID_8088 占用8088端口"
            kill $PID_8088 2>/dev/null || true
            sleep 2
            
            if ps -p $PID_8088 > /dev/null 2>&1; then
                echo "⚠️  强制终止进程 $PID_8088"
                kill -9 $PID_8088 2>/dev/null || true
                sleep 1
            fi
            echo "✅ 8088端口已释放"
        fi
    else
        echo "✅ 8088端口未被占用"
    fi
    
    # 检查4433端口是否被占用
    if netstat -tlnp 2>/dev/null | grep -q ":4433 " || ss -tlnp 2>/dev/null | grep -q ":4433 "; then
        echo "⚠️  检测到4433端口被占用，正在释放..."
        
        PID_4433=$(netstat -tlnp 2>/dev/null | grep ":4433 " | awk '{print $7}' | cut -d'/' -f1 | head -1)
        if [ -z "$PID_4433" ]; then
            PID_4433=$(ss -tlnp 2>/dev/null | grep ":4433 " | grep -oP 'pid=\K[0-9]+' | head -1)
        fi
        
        if [ -n "$PID_4433" ]; then
            echo "📍 发现进程 PID=$PID_4433 占用4433端口"
            kill $PID_4433 2>/dev/null || true
            sleep 2
            
            if ps -p $PID_4433 > /dev/null 2>&1; then
                echo "⚠️  强制终止进程 $PID_4433"
                kill -9 $PID_4433 2>/dev/null || true
                sleep 1
            fi
            echo "✅ 4433端口已释放"
        fi
    else
        echo "✅ 4433端口未被占用"
    fi
    
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "🔧 设置权限..."
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    
    # 设置权限
    chmod +x bin/server
    if [ -f "service.sh" ]; then
        chmod +x service.sh
    fi
    
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "🚀 启动服务..."
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    
    # 启动服务
    nohup ./bin/server > logs/server.log 2>&1 &
    SERVER_PID=$!
    echo $SERVER_PID > logs/server.pid
    
    echo "📍 服务PID: $SERVER_PID"
    sleep 3
    
    # 验证启动
    if ps -p $SERVER_PID > /dev/null 2>&1; then
        echo "✅ 服务启动成功"
    else
        echo "❌ 服务启动失败！"
        echo "📝 查看错误日志:"
        tail -n 20 logs/server.log
        exit 1
    fi
START_EOF

if [ $? -eq 0 ]; then
    print_success "服务启动成功！"
else
    print_error "服务启动失败！"
    exit 1
fi

# 等待服务完全启动
echo ""
echo "⏳ 等待服务完全启动..."
sleep 8

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 第四步：输出启动日志
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
print_step "📝 第四步：输出启动日志"

ssh_exec << 'LOG_EOF'
    cd /root/internalNetBridge/server
    
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "📊 服务状态"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    
    # 进程信息
    if pgrep -f "bin/server" > /dev/null; then
        PID=$(pgrep -f "bin/server" | head -1)
        echo "✅ 进程运行: PID=$PID"
        ps aux | grep "$PID" | grep -v grep | awk '{print "   CPU: "$3"%, MEM: "$4"%, 启动时间: "$9}'
    else
        echo "❌ 进程未运行"
    fi
    
    echo ""
    
    # 端口监听
    echo "📡 端口监听:"
    netstat -tlnp 2>/dev/null | grep -E ":8088|:4433" || ss -tlnp 2>/dev/null | grep -E ":8088|:4433" || echo "   ⚠️  未检测到端口监听"
    
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "📝 最近30行日志"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    tail -n 30 logs/server.log
LOG_EOF

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 部署完成总结
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
print_step "🎉 部署完成！"

echo ""
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}✨ 部署摘要${NC}"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "🔨 编译方式: 本地交叉编译 (linux/amd64)"
echo -e "📤 部署方式: 上传二进制文件"
echo -e "🚀 服务状态: ✅ 运行中"
echo -e "🌐 服务地址: http://$REMOTE_HOST:8088"
echo -e "🔐 QUIC端口: $REMOTE_HOST:4433"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e "${YELLOW}📋 常用命令:${NC}"
echo ""
echo "# 查看服务状态"
echo "ssh root@$REMOTE_HOST 'cd $REMOTE_PATH && ./service.sh status'"
echo ""
echo "# 重启服务"
echo "ssh root@$REMOTE_HOST 'cd $REMOTE_PATH && ./service.sh restart'"
echo ""
echo "# 停止服务"
echo "ssh root@$REMOTE_HOST 'cd $REMOTE_PATH && ./service.sh stop'"
echo ""
print_success "🎊 部署流程全部完成！"

# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 实时查看日志
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
echo ""
print_step "📺 实时查看服务日志（按 Ctrl+C 退出）"
echo ""
echo -e "${YELLOW}💡 提示：如果看到错误，请按 Ctrl+C 退出后运行以下命令重启：${NC}"
echo -e "   ssh root@$REMOTE_HOST 'cd $REMOTE_PATH && ./service.sh restart'"
echo ""
sleep 2

# 实时查看日志
if [ "$USE_SSHPASS" = true ]; then
    sshpass -p "$REMOTE_PASSWORD" ssh -tt -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" "stdbuf -oL -eL tail -f $REMOTE_PATH/logs/server.log"
elif [ "$USE_EXPECT" = true ]; then
    export EXPECT_PASSWORD="$REMOTE_PASSWORD"
    export EXPECT_USER="$REMOTE_USER"
    export EXPECT_HOST="$REMOTE_HOST"
    export EXPECT_PATH="$REMOTE_PATH"
    
    /usr/bin/expect <<'EOFLOG'
set timeout -1
set password $env(EXPECT_PASSWORD)
set user $env(EXPECT_USER)
set host $env(EXPECT_HOST)
set path $env(EXPECT_PATH)

log_user 0
spawn ssh -tt -o StrictHostKeyChecking=no $user@$host "stdbuf -oL -eL tail -f $path/logs/server.log"

expect {
    -nocase "password:" {
        send "$password\r"
        log_user 1
        exp_continue
    }
    -re ".+\r\n" {
        puts -nonewline $expect_out(0,string)
        flush stdout
        exp_continue
    }
    eof {
        exit 0
    }
    timeout {
        exp_continue
    }
}
EOFLOG
else
    ssh -tt -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" "stdbuf -oL -eL tail -f $REMOTE_PATH/logs/server.log"
fi
